---
id: cors
title: 15. CORS 跨域
sidebar_label: 15. CORS 跨域
---

## 15.1 什么是跨域

简单来说，当一个请求 `url` 的协议、域名、端口三者之间任意一个与当前页面 `url` 不同即为跨域。那为什么会出现跨域问题呢？

出于浏览器的同源策略限制。同源策略（Sameoriginpolicy）是一种约定，它是浏览器最核心也最基本的安全功能，如果缺少了同源策略，则浏览器的正常功能可能都会受到影响。可以说 `Web` 是构建在同源策略基础之上的，浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的 javascript 脚本和另外一个域的内容进行交互。所谓同源（即指在同一个域）就是两个页面具有相同的协议（protocol），主机（host）和端口号（port）

## 15.2 有跨域行为示例

| 当前页面 url                  | 被请求页面 url                      | 是否跨域 | 原因                           |
| ----------------------------- | ----------------------------------- | -------- | ------------------------------ |
| http://www.furos.cn/      | http://www.furos.cn/index.html  | 否       | 同源（协议、域名、端口号相同） |
| http://www.furos.cn/      | https://www.furos.cn/index.html | 跨域     | 协议不同（http/https）         |
| http://www.furos.cn/      | http://www.baidu.com/               | 跨域     | 主域名不同（chinadot/baidu）   |
| http://www.furos.cn/      | http://blog.furos.cn/           | 跨域     | 子域名不同（www/blog）         |
| http://www.furos.cn:8080/ | http://www.furos.cn:7001/       | 跨域     | 端口号不同（8080/7001）        |

## 15.3 什么是 CORS

跨源资源共享 (`CORS`) ：

- 是一种 `W3C` 标准，可让服务器放宽相同的源策略。
- 不是一项安全功能，`CORS` 放宽 `security`。 `API` 不能通过允许 `CORS` 来更安全。 有关详细信息，请参阅 [CORS 工作原理](https://docs.microsoft.com/zh-cn/aspnet/core/security/cors?view=aspnetcore-5.0#how-cors)。
- 允许服务器明确允许一些跨源请求，同时拒绝其他请求。
- 比早期的技术（如 JSONP）更安全且更灵活。

## 15.4 如何使用

### 15.4.1 添加 `CORS` 服务

启用跨域 `Cors` 支持首先添加 `CorsAccessor` 服务，如：

```cs {13,22}
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace Fur.Web.Core
{
    [AppStartup(700)]
    public sealed class FurWebCoreStartup : AppStartup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCorsAccessor();

            // ...
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            //...

            app.UseCorsAccessor();

            // ...
        }
    }
}
```

:::caution 特别注意

`services.AddCorsAccessor();` 需在 `services.AddControllers()` 之前注册。

`app.UseCorsAccessor();` 需在 `app.UseRouting();` 和 `app.UseAuthentication();` 之间注册。

:::

### 15.4.2 配置允许跨域域名

:::important 小提醒

默认情况下，`Fur` 允许所有域名来源访问，也就是无需配置任何来源域名，另外前端也需要设置请求参数：`withCredentials:false`

:::

如果需要指定特定域名，则添加以下配置即可：

```json {4}
{
  "CorsAccessorSettings": {
    "PolicyName": "自定义跨域策略名",
    "WithOrigins": ["http://localhost:4200", "https://furos.cn"]
  }
}
```

## 15.5 `CorsAccessorSettings` 配置

- `CorsAccessorSettings`
  - `PolicyName`：跨域策略名，字符串类型，必填，默认 `FurCorsAccessor`
  - `WithOrigins`：允许跨域的域名列表，字符串数组类型，默认 `[ "http://localhost:4200" ]`
  - `WithHeaders`：请求表头，没有配置则允许所有表头，字符串数组类型
  - `WithExposedHeaders`：响应标头，字符串数组类型
  - `WithMethods`：设置跨域允许请求谓词，没有配置则允许所有，字符串数组类型
  - `AllowCredentials`：跨域请求中的凭据，`bool` 类型
  - `SetPreflightMaxAge`：设置预检过期时间，`int` 类型

## 15.6 反馈与建议

:::note 与我们交流

给 Fur 提 [Issue](https://gitee.com/monksoul/Fur/issues/new?issue)。

:::

---

:::note 了解更多

想了解更多 `跨域请求` 知识可查阅 [ASP.NET Core - 启用跨域请求](https://docs.microsoft.com/zh-cn/aspnet/core/security/cors?view=aspnetcore-5.0) 章节。

:::
